import type { HlsConfig } from 'hls.js';
import Hls from 'hls.js';

// 为Hls类增加元数据属性
declare module 'hls.js' {
  interface Hls {
    metadata?: {
      duration?: number;
      bitrates?: number[];
      resolution?: string;
    };
  }
}

// 扩展HTMLVideoElement以支持存储Hls实例
declare global {
  interface HTMLVideoElement {
    hlsPlayer?: Hls;
  }
}

// 元数据类型定义
interface StreamMetadata {
  duration?: number;
  bitrates?: number[];
  resolution?: string;
}

/**
 * HLS播放器
 */
export class HlsPlayer {
  private static instances = new Set<Hls>();
  private static metadataCache = new WeakMap<Hls, StreamMetadata>();

  /**
   * 初始化播放器
   */
  public static init(): void {
    // 页面卸载时清理资源
    if (typeof window !== 'undefined') {
      window.addEventListener('beforeunload', () => {
        this.destroy();
      });
    }
  }

  /**
   * 加载视频流
   */
  public static load(video: HTMLVideoElement, url: string): Hls {
    // 清理旧实例
    this.detach(video);

    // 创建新实例，使用优化配置
    const hls = new Hls({
      // 缓冲区配置优化
      maxBufferLength: 30,           // 最大缓冲长度（秒）
      maxMaxBufferLength: 60,        // 最大缓冲长度上限
      maxBufferSize: 60 * 1000 * 1000, // 最大缓冲大小（60MB）
      maxBufferHole: 0.5,            // 最大缓冲洞大小

      // 错误恢复配置
      fragLoadingTimeOut: 20000,     // 分片加载超时
      manifestLoadingTimeOut: 10000, // 清单加载超时

      // 启用更好的错误恢复
      enableWorker: true,            // 启用Web Worker
      lowLatencyMode: false,         // 禁用低延迟模式以提高稳定性
    });
    // const hls = new Hls();

    this.instances.add(hls);
    video.hlsPlayer = hls;

    // 添加错误恢复计数器
    let mediaErrorCount = 0;
    let networkErrorCount = 0;
    const maxRetries = 3;

    // 加载源
    hls.loadSource(url);
    hls.attachMedia(video);

    // 收集基本信息
    hls.on(Hls.Events.MANIFEST_PARSED, (_, data) => {
      // 收集流媒体信息
      const metadata: StreamMetadata = {
        duration: data.levels[0]?.details?.totalduration,
        bitrates: data.levels.map(level => level.bitrate),
        resolution: data.levels[0] ? `${data.levels[0].width}x${data.levels[0].height}` : undefined
      };

      this.metadataCache.set(hls, metadata);
    });

    // 监听媒体附加事件来重置错误计数器
    hls.on(Hls.Events.MEDIA_ATTACHED, () => {
      console.log('[HLS] 媒体已重新附加，重置错误计数器');
      mediaErrorCount = 0;
      networkErrorCount = 0;
    });

    return hls;
  }

  /**
   * 释放视频元素绑定
   */
  public static detach(video: HTMLVideoElement): void {
    if (!video) return;
    
    const hls = video.hlsPlayer;
    if (hls) {
      try {
        // 1. 先暂停加载
        hls.stopLoad();
        
        // 2. 分离媒体元素
        hls.detachMedia();
        
        // 3. 然后销毁实例
        hls.destroy();
        
        // 4. 从实例集合中移除
        this.instances.delete(hls);
        
        // 5. 清除视频元素的引用
        video.hlsPlayer = undefined;
        
        // 6. 清除视频元素的src，完全释放资源
        video.src = '';
        video.load();
      } catch (e) {
        console.warn('[HLS] 释放实例失败', e);
      }
    }
  }

  /**
   * 获取视频元数据
   */
  public static getMetadata(video: HTMLVideoElement): StreamMetadata | undefined {
    return video.hlsPlayer ? this.metadataCache.get(video.hlsPlayer) : undefined;
  }

  /**
   * 释放所有资源
   */
  public static destroy(): void {
    try {
      // 复制实例集合，防止在迭代时修改集合
      const instancesCopy = Array.from(this.instances);
      
      // 销毁所有实例
      for (const hls of instancesCopy) {
        try {
          hls.stopLoad();
          hls.destroy();
          this.instances.delete(hls);
        } catch (e) {
          // 忽略单个实例的错误
        }
      }
    } catch (e) {
      console.error('[HLS] 销毁所有资源失败', e);
    }
  }
}

// 自动初始化
if (typeof window !== 'undefined') {
  HlsPlayer.init();
} 